using Comteck.Utils;
using Comteck.Winforms.Properties;
using DevExpress.Utils;
using DevExpress.Utils.Menu;
using DevExpress.XtraBars;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Drawing;
using DevExpress.XtraEditors.Repository;
using DevExpress.XtraEditors.ViewInfo;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraGrid.Views.BandedGrid;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
using DevExpress.XtraPrinting;
using DevExpress.XtraTabbedMdi;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq.Expressions;
using System.Reflection;
using System.Windows.Forms;
using WinForms = System.Windows.Forms;
using System.Linq;
using System.Data;
using System.Threading.Tasks;
using System.Net;

namespace Comteck.Winforms {
  /// <summary>
  /// DevExpress帮助类
  /// </summary>
  public static partial class DevExtensions {


    #region 设置LookUpEdit的选中值,忽略类型及大小写

    /// <summary>
    /// 设置LookUpEdit的选中值,忽略类型及大小写 add by weijie.sun 2013/10/14
    /// </summary>
    /// <param name="control">LookUpEdit</param>
    /// <param name="value">默认选中值</param>
    /// <returns>选中值</returns>
    public static object SetEditValue2(this LookUpEdit control, object value) {
      // LookUpEdit is null
      if (control == null) {
        return value;
      }

      // value or datasource is null
      if (value == null || control.Properties.DataSource == null) {
        control.ItemIndex = -1;
        return value;
      }

      // 行号
      var index = 0;

      while (true) {
        // 查找value值
        var itemValue = control.Properties.GetDataSourceValue(control.Properties.ValueMember, index);

        // 如果value没有找到,则表示到末尾了
        if (itemValue == null) {
          break;
        }

        // 如果值相等
        if (itemValue.ToString().Equals(value.ToString(), StringComparison.OrdinalIgnoreCase)) {
          control.ItemIndex = index;
          break;
        }

        index++;
      }

      return value;
    }

    #endregion

    #region 根据条件删除List中的记录，对象保持不变

    /// <summary>
    /// 根据条件删除List中的记录，对象保持不变 add by weijie.sun 2013/10/26
    /// </summary>
    /// <typeparam name="T">指定类型的对象</typeparam>
    /// <param name="gridView">Dev GridView</param>
    /// <param name="func">表达式</param>
    public static IList<T> RemoveAll<T>(this GridView gridView, Expression<Func<T, bool>> func) {
      // 删除的行
      IList<T> list = new List<T>();

      // null
      if (gridView == null) {
        return list;
      }

      // 结束编辑
      gridView.UpdateCurrentRow();
      gridView.CloseEditor();

      // 编译
      var func2 = func.Compile();

      // 总记录数
      var count = gridView.RowCount;

      // 倒叙删除
      for (var i = count - 1; i >= 0; i--) {
        // 数据源
        var model = (T)gridView.GetRow(i);

        // no data
        if (model == null) {
          continue;
        }

        // 执行方法
        var flag = func2(model);

        // 如果符合条件则删除
        if (flag) {
          gridView.DeleteRow(i);
          list.Add(model);
        }
      }

      return list;
    }

    #endregion

    #region 添加选择列 add by weijie.sun 2013/10/28

    /// <summary>
    /// 添加选择列 add by weijie.sun 2013/10/28
    /// </summary>
    /// <param name="gridView">Dev GridView</param>
    /// <param name="column">Dev GridColumn</param>
    /// <param name="dataSourceChange">当数据源改变时,是否全选或全部选</param>
    /// <param name="width">列宽</param>
    public static void AddCheckBoxHeadCell(this GridView gridView, GridColumn column,
      bool dataSourceChange = false, int width = 40) {
      // gridView
      if (gridView == null) {
        throw new System.ArgumentNullException("gridView");
      }

      // 头部列名为空
      if (column == null || String.IsNullOrWhiteSpace(column.FieldName)) {
        throw new System.ArgumentNullException("column");
      }

      // 是否选中(局部变量)
      var isChecked = false;

      // 设置列的属性
      column.Width = width;
      column.OptionsColumn.AllowSort = DevExpress.Utils.DefaultBoolean.False;
      //  column.Caption = String.Empty;
      column.OptionsColumn.ShowCaption = false;

      // 鼠标单击事件
      gridView.Click += (sender, e) => {
        ClickGridCheckBox(gridView, column, ref isChecked, true);
      };

      // 重绘事件
      gridView.CustomDrawColumnHeader += (sender, e) => {
        if (e.Column != null && e.Column == column) {
          e.Info.InnerElements.Clear();
          e.Painter.DrawObject(e.Info);
          DrawCheckBox(e, column, isChecked);
          e.Handled = true;
        }
      };

      // 数据源改变
      if (dataSourceChange) {
        gridView.DataSourceChanged += (sender, e) => {
          ClickGridCheckBox(gridView, column, ref isChecked, false);
        };
      }
    }

    /// <summary>
    /// 重绘头部复选框
    /// </summary>
    /// <param name="e">ColumnHeaderCustomDrawEventArgs</param>
    /// <param name="column">待重绘的列</param>
    /// <param name="isChecked">是否选中</param>
    public static void DrawCheckBox(ColumnHeaderCustomDrawEventArgs e, GridColumn column, bool isChecked) {
      // 如果不是复选框列,则不作处理
      if (e.Column != column) {
        return;
      }

      // 复选框的列
      var repositoryCheck = e.Column.ColumnEdit as RepositoryItemCheckEdit;

      // not RepositoryItemCheckEdit
      if (repositoryCheck == null) {
        throw new Exception("Column must be a RepositoryItemCheckEdit");
      }

      // 画笔
      Graphics g = e.Graphics;

      // 矩形
      Rectangle r = e.Bounds;


      // dev objects
      CheckEditViewInfo info = repositoryCheck.CreateViewInfo() as CheckEditViewInfo;

      // 选中值
      info.EditValue = isChecked ? repositoryCheck.ValueChecked : repositoryCheck.ValueUnchecked;

      var sizeF = g.MeasureString(repositoryCheck.Caption, repositoryCheck.Appearance.Font);
      float left = (r.Width - sizeF.Width - 40) / 2;
      float top = (r.Height - sizeF.Height) / 2 / 2;
      info.Bounds = new Rectangle(r.Left + (int)left, r.Top, 40, r.Height);
      info.CalcViewInfo(g);

      CheckEditPainter painter = repositoryCheck.CreatePainter() as CheckEditPainter;
      ControlGraphicsInfoArgs args = new ControlGraphicsInfoArgs(info, new DevExpress.Utils.Drawing.GraphicsCache(g), r);

      painter.Draw(args);
      // SolidBrush brush = new SolidBrush(repositoryCheck.Appearance.BackColor);
      repositoryCheck.Appearance.DrawString(args.Cache, repositoryCheck.Caption, new Rectangle(r.Left + (int)left + 40, r.Top - (int)top, r.Width - 40 - (int)left, r.Height));
      args.Cache.Dispose();
    }

    /// <summary>
    /// 根据条件全选或者全不选所有行
    /// </summary>
    /// <param name="gridView"></param>
    /// <param name="column"></param>
    /// <param name="isChecked">是否选中</param>
    /// <param name="changeChecked">是否改变选中状态</param>
    public static void ClickGridCheckBox(GridView gridView, GridColumn column, ref bool isChecked, bool changeChecked) {
      // 提交修改
      gridView.PostEditor();

      // 选择列
      RepositoryItemCheckEdit c = null;

      if (changeChecked) {

        // 取得当前鼠标的位置
        Point pt = gridView.GridControl.PointToClient(Control.MousePosition);

        // 点击的信息
        GridHitInfo info = gridView.CalcHitInfo(pt);

        // 如果不在点击范围内,或者非复选框列
        if (info.InColumnPanel == false || info.Column == null || info.Column != column) {
          return;
        }

        // 选择列
        c = info.Column.ColumnEdit as RepositoryItemCheckEdit;

        // 置为反值
        isChecked = !isChecked;
      } else {
        c = column.ColumnEdit as RepositoryItemCheckEdit;
      }

      // 获取值
      var value = isChecked ? c.ValueChecked : c.ValueUnchecked;

      // 设置值
      for (int i = 0; i < gridView.RowCount; i++) {
        gridView.SetRowCellValue(i, column, isChecked);
      }
    }

    #endregion

    #region 只能选择一行 add by weijie.sun 2013/11/22

    /// <summary>
    /// 只能选择一行 add by weijie.sun 2013/11/22
    /// </summary>
    /// <param name="gridView">Dev GridView</param>
    /// <param name="column">Dev GridColumn</param>
    /// <param name="dataSourceChange">当数据源改变时,是否全选或全部选</param>
    /// <param name="width">列宽</param>
    public static void AddCheckBoxSingle(this GridView gridView, GridColumn column) {
      // gridView
      if (gridView == null) {
        throw new System.ArgumentNullException("gridView");
      }

      // 头部列名为空
      if (column == null || String.IsNullOrWhiteSpace(column.FieldName)) {
        throw new System.ArgumentNullException("column");
      }

      // 编辑行
      var columnEdit = column.ColumnEdit as RepositoryItemCheckEdit;
      if (columnEdit == null) {
        return;
      }

      columnEdit.Click += (sender, e) => {
        // 不在有效行中
        if (gridView.FocusedRowHandle <= -1) {
          return;
        }

        // 结束编辑行
        gridView.CloseEditor();
        gridView.UpdateCurrentRow();

        // 先取消原先全部选中的行
        for (int i = 0; i < gridView.RowCount; i++) {
          gridView.SetRowCellValue(i, column, columnEdit.ValueUnchecked);
        }

        // 再将当前的行选中
        gridView.SetRowCellValue(gridView.FocusedRowHandle, column, columnEdit.ValueChecked);
      };

      // 鼠标单击事件
      gridView.Click += (sender, e) => {
        // 不在有效行中
        if (gridView.FocusedRowHandle <= -1) {
          return;
        }

        // 先取消原先全部选中的行
        for (int i = 0; i < gridView.RowCount; i++) {
          gridView.SetRowCellValue(i, column, columnEdit.ValueUnchecked);
        }

        // 再将当前的行选中
        gridView.SetRowCellValue(gridView.FocusedRowHandle, column, columnEdit.ValueChecked);
      };
    }

    #endregion

    #region 按下回车键到下个控件

    /// <summary>
    /// 按下回车键到下个控件
    /// </summary>
    /// <param name="control"></param>
    public static void EnterMoveToNextControlDev(this WinForms.Control container) {
      // 控件容器为空
      if (container == null) {
        throw new ArgumentNullException("container", "请确定WinForms.Control container容器不为空！");
      }

      //// 待返回的对象
      //var list = new List<DataFilter>();
      //DataFilter filter = null;

      // 取得容器的所有控件
      WinForms.Control.ControlCollection controls = container.Controls;

      // 容器内没有控件
      if (controls == null || controls.Count == 0) {
        return;
      }

      // 遍历所有控件
      foreach (WinForms.Control control in controls) {
        // tag的值
        var baseEdit = control as BaseEdit;

        if (baseEdit == null) {
          continue;
        }

        // 启用回车键换控件
        baseEdit.EnterMoveNextControl = true;

        // 向后找到下一个对象
        var nextControl = control.GetNextControl(control, true);

        // 没有找到
        if (nextControl == null) {
          continue;
        }
      }
    }

    #endregion

    #region GridView 显示行号

    /// <summary>
    /// 设置GridView的序号
    /// </summary>
    /// <param name="gv">GridView</param>
    /// <returns></returns>
    public static GridView SetRowNumber(this GridView gv) {
      return SetRowNumber(gv, 45);
    }

    /// <summary>
    /// 设置GridView的序号
    /// </summary>
    /// <param name="gv">GridView</param>
    /// <param name="width">序号的宽度</param>
    /// <returns></returns>
    public static GridView SetRowNumber(this GridView gv, int width) {
      return SetRowNumber(gv, 0, 0, width);
    }

    /// <summary>
    /// 设置GridView的序号
    /// </summary>
    /// <param name="gv">GridView</param>
    /// <param name="pageIndex">当前页码</param>
    /// <param name="pageSize">每页大小</param>
    /// <returns></returns>
    public static GridView SetRowNumber(this GridView gv, int pageIndex, int pageSize) {
      return SetRowNumber(gv, pageIndex, pageSize, 40);
    }

    /// <summary>
    /// 设置GridView的序号
    /// </summary>
    /// <param name="gv">GridView</param>
    /// <param name="pageIndex">当前页码</param>
    /// <param name="pageSize">每页大小</param>
    /// <param name="width">序号的宽度</param>
    /// <returns></returns>
    public static GridView SetRowNumber(this GridView gv, int pageIndex, int pageSize, int width) {
      // 设置宽度
      gv.IndicatorWidth = width;

      // 起始行
      var startRow = Math.Max(pageIndex - 1, 0) * pageSize;

      // 重画行号
      gv.CustomDrawRowIndicator += new RowIndicatorCustomDrawEventHandler((sender, e) => {
        // 设置行号
        if (e.Info.IsRowIndicator && e.RowHandle >= 0) {
          e.Info.DisplayText = (startRow + e.RowHandle + 1).ToString();
        }
      });

      return gv;
    }

    #endregion

    #region 批量设置列的值（适合于全选和全不选）

    /// <summary>
    /// 设置GridView全选
    /// </summary>
    /// <param name="gv">GridView</param>
    /// <param name="selectColumn">复选框列</param>
    /// <returns></returns>
    public static GridView SetGridViewSelect(this GridView gv, GridColumn selectColumn) {
      return SetGridViewSelect(gv, selectColumn, true);
    }

    /// <summary>
    /// 设置GridView全选
    /// </summary>
    /// <param name="gv">GridView</param>
    /// <param name="selectColumn">复选框列</param>
    /// <param name="value">全选的值</param>
    /// <returns></returns>
    public static GridView SetGridViewSelect(this GridView gv, GridColumn selectColumn, object value) {
      for (var i = 0; i < gv.RowCount; i++) {
        gv.SetRowCellValue(i, selectColumn, value);
      }

      return gv;
    }

    #endregion

    #region 反选

    /// <summary>
    /// 设置GridView反选
    /// </summary>
    /// <param name="gv">GridView</param>
    /// <param name="selectColumn">复选框列</param>
    /// <returns></returns>
    public static GridView SetGridViewSelectInvert(this GridView gv, GridColumn selectColumn) {
      //for (var i = 0; i < gv.RowCount; i++) {
      //  bool isSelect = gv.GetRowCellValue(i, selectColumn).ToBoolean();
      //  gv.SetRowCellValue(i, selectColumn, !isSelect);
      //}

      for (var i = 0; i < gv.RowCount; i++) {
        var isSelect = gv.GetRowCellValue(i, selectColumn).To<int>();
        isSelect = isSelect == 1 ? 0 : 1;
        gv.SetRowCellValue(i, selectColumn, isSelect);
      }

      return gv;
    }

    #endregion

    #region 输入法状态

    /// <summary>
    /// 设置输入法状态
    /// </summary>
    /// <param name="form">XtraForm,如表单Form</param>
    /// <param name="mode">模式</param>
    /// <returns>返回本对象</returns>
    public static XtraForm SetImeMode_Dev(this XtraForm form, ImeMode mode) {
      // 类型
      var type = form.GetType();

      // 查找所有的字段field
      var fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic);

      // 遍历
      foreach (var fi in fields) {
        // 如果是文本编辑器，默认为无输入法
        if (fi.FieldType == typeof(TextEdit) || fi.FieldType == typeof(LookUpEdit)) {

          TextEdit c = fi.GetValue(form) as TextEdit;
          if (c != null) {
            c.ImeMode = mode;
          }
        }
      }

      return form;
    }

    #endregion

    #region GridView 编辑选中

    /// <summary>
    /// 设置编辑状态的全选操作
    /// </summary>
    /// <param name="gc">GridView</param>
    /// <param name="ignoreCheck">是否忽略复选框</param>
    /// <returns></returns>
    public static void SetEditorFocus(this GridControl gc, bool ignoreCheck = false) {
      // no data
      if (gc == null) {
        return;
      }

      var gv = gc.MainView as GridView;
      gv.OptionsBehavior.EditorShowMode = DevExpress.Utils.EditorShowMode.MouseUp;

      gv.MouseUp += (sender, e) => {
        // 非左键
        if (e.Button != MouseButtons.Left) {
          return;
        }

        GridView view = null;

        // 传递对象
        if (sender is BandedGridView) {
          view = sender as BandedGridView;
        } else if (sender is GridView) {
          view = sender as GridView;
        }

        // 选择多列
        if (view.GetSelectedCells().Length > 1) {
          return;
        }

        // 选中的区域
        GridHitInfo hi = view.CalcHitInfo(e.Location);

        // 不在单元格中
        if (hi.InRowCell == false) {
          return;
        }

        // 不能编辑
        if (hi.Column.OptionsColumn.AllowEdit == false) {
          return;
        }

        // 根据不同列分别处理
        if (hi.Column.RealColumnEdit is RepositoryItemCheckEdit) {
          if (ignoreCheck == false) {
            view.FocusedColumn = hi.Column;
            view.FocusedRowHandle = hi.RowHandle;

            var columnEdit = (RepositoryItemCheckEdit)hi.Column.RealColumnEdit;
            object value2 = null;
            var value = view.GetRowCellValue(hi.RowHandle, hi.Column);
            //var value = view.GetFocusedRowCellValue(view.FocusedColumn);
            if (value.To<int>() == columnEdit.ValueChecked.To<int>()) {
              value2 = columnEdit.ValueUnchecked;
            } else {
              value2 = columnEdit.ValueChecked;
            }

            view.SetFocusedRowCellValue(view.FocusedColumn, value2);
          }
        } else if ((hi.Column.RealColumnEdit as RepositoryItemPopupBase) != null) {
          view.FocusedColumn = hi.Column;
          view.FocusedRowHandle = hi.RowHandle;
          gc.BeginInvoke(new MethodInvoker(delegate () {
            if (view.ActiveEditor is PopupBaseEdit) {
              view.ShowEditor();
              (view.ActiveEditor as PopupBaseEdit).ShowPopup();
            }
          }));
        }
      };

    }

    #endregion

    #region 获取选中行的数据集合

    /// <summary>
    /// 获取选中行的数据集合
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="gv"></param>
    /// <returns></returns>
    //public static List<T> GetSelectedRowsList<T>(this GridView gv) where T : class, new() {
    //  // 获取选中行的
    //  var rowIds = gv.GetSelectedRows();

    //  return rowIds?.Where(x => x >= 0).Select(x => gv.GetRow(x) as T).ToList();
    //}

    /// <summary>
    /// 获取GridView的选中行数据集（数据源是 DataTable） add by geping@2019-01-05
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="gv"></param>
    /// <returns></returns>
    public static List<T> GetSelectedDataRows<T>(this GridView gv) where T : class, new() {
      var list = new List<T>();
      var rowIds = gv.GetSelectedRows();

      foreach (var id in rowIds) {
        var entity = Comteck.Extensions.DataTableExtensions.ToModel<T>((gv.GetRow(id) as DataRowView).Row);
        if (entity == null) continue;

        list.Add(entity);
      }
      return list;
    }
    #endregion

    #region 复制单元格

    /// <summary>
    /// 复制单元格
    /// </summary>
    /// <param name="gridview">GridView</param>
    /// <returns></returns>
    public static void EnableCopyCell(this GridView gridview) {
      gridview.KeyDown += (sender, e) => {
        if (e.Control & e.KeyCode == Keys.C) {
          Clipboard.SetDataObject(gridview.GetFocusedRowCellValue(gridview.FocusedColumn));
          e.Handled = true;
        }
      };
    }

    #endregion

    #region 鼠标右键

    /// <summary>
    /// 鼠标右键
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    public static void MyGridView_PopupMenuShowing(object sender, PopupMenuShowingEventArgs e) {
      // 对象
      var gridView = sender as GridView;
      if (gridView == null) {
        return;
      }

      // 非自定义列
      if (e.HitInfo.InGroupPanel || e.HitInfo.InFilterPanel || e.MenuType == GridMenuType.Column) {
        return;
      }

      if (e.MenuType == GridMenuType.Row) {

        //// 保存布局
        //var menu_SaveLayout = new DXMenuItem("保存布局");
        //menu_SaveLayout.Image = Resources.copy_16x16;
        //e.Menu.Items.Add(menu_SaveLayout);

        //// 还原布局
        //var menu_RestoreLayout = new DXMenuItem("恢复原有样式");
        //menu_RestoreLayout.Image = Resources.copy_16x16;
        //e.Menu.Items.Add(menu_RestoreLayout);


        #region 复制

        // 复制
        var menu_copy = new DXSubMenuItem("复制");
        menu_copy.BeginGroup = true;
        menu_copy.Image = Resources.copy_16x16;

        // 复制单元格
        var menu_copy_cell = new DXMenuItem("单元格(&C)");
        menu_copy_cell.Image = Resources.copy_16x16;
        menu_copy_cell.Click += (x, y) => {
          Clipboard.SetDataObject(gridView.GetFocusedRowCellDisplayText(gridView.FocusedColumn));

        };

        // 复制选中行
        var menu_copy_select = new DXMenuItem("选中行");
        menu_copy_select.Image = Resources.copy_16x16;
        menu_copy_select.Click += (x, y) => {
          gridView.CopyToClipboard();
          //Clipboard.SetDataObject(gridView.GetSelectedCells());
        };

        // 复制全部数据
        var menu_copy_all = new DXMenuItem("全部数据");
        menu_copy_all.Image = Resources.copy_16x16;
        menu_copy_all.Click += (x, y) => {
          var selectedRows = gridView.GetSelectedRows();

          string resultString = string.Empty;
          gridView.BeginUpdate();
          gridView.SelectAll();
          MethodInfo mi = typeof(DevExpress.XtraGrid.Views.Grid.GridView).GetMethod("GetText", BindingFlags.Instance | BindingFlags.NonPublic);
          resultString = mi.Invoke(gridView, null).ToString();
          gridView.ClearSelection();
          gridView.EndUpdate();

          DataObject data = new DataObject();
          data.SetData(typeof(string), resultString);
          Clipboard.SetDataObject(data);

          foreach (var rowNum in selectedRows) {
            gridView.SelectRow(rowNum);
          }
        };

        menu_copy.Items.Add(menu_copy_cell);
        menu_copy.Items.Add(menu_copy_select);
        menu_copy.Items.Add(menu_copy_all);

        e.Menu.Items.Add(menu_copy);

        #endregion

        #region 导出

        // 导出
        var menu_export = new DXSubMenuItem("导出");
        menu_export.Image = Resources.export_16x16;
        //menu_export.Image = DevExpress.Images.ImageResourceCache.Default.GetImage("images/export/export_16x16.png");

        // 导出到 XLS
        var menu_export_XLS = new DXMenuItem("导出到 XLS");
        menu_export_XLS.Image = Resources.exporttoxls_16x16;
        menu_export_XLS.Click += (x, y) => {
          ExportDialog(gridView, ExportTarget.Xls);
        };

        // 导出到 XLSX
        var menu_export_XLSX = new DXMenuItem("导出到 XLSX");
        menu_export_XLSX.Image = Resources.exporttoxlsx_16x16;
        menu_export_XLSX.Click += (x, y) => {
          ExportDialog(gridView, ExportTarget.Xlsx);
        };

        // 导出到 PDF
        var menu_export_PDF = new DXMenuItem("导出到 PDF");
        menu_export_PDF.Image = Resources.exporttopdf_16x16;
        menu_export_PDF.Click += (x, y) => {
          ExportDialog(gridView, ExportTarget.Pdf);
        };

        // 导出到 HTML
        var menu_export_HTML = new DXMenuItem("导出到 HTML");
        menu_export_HTML.Image = Resources.exporttohtml_16x16;
        menu_export_HTML.Click += (x, y) => {
          ExportDialog(gridView, ExportTarget.Html);
        };
        menu_export_HTML.BeginGroup = true;

        // 导出到 Text
        var menu_export_TEXT = new DXMenuItem("导出到 Text") {
          Image = Resources.exporttotxt_16x16
        };
        menu_export_TEXT.Click += (x, y) => {
          ExportDialog(gridView, ExportTarget.Text);
        };

        // 导出到 MHT
        var menu_export_MHT = new DXMenuItem("导出到 MHT");
        menu_export_MHT.Image = Resources.exporttomht_16x16;
        menu_export_MHT.Click += (x, y) => {
          ExportDialog(gridView, ExportTarget.Mht);
        };

        // 导出到 RTF
        var menu_export_RTF = new DXMenuItem("导出到 RTF");
        menu_export_RTF.Image = Resources.exporttortf_16x16;
        menu_export_RTF.Click += (x, y) => {
          ExportDialog(gridView, ExportTarget.Rtf);
        };

        menu_export.Items.Add(menu_export_XLS);
        menu_export.Items.Add(menu_export_XLSX);
        menu_export.Items.Add(menu_export_PDF);
        menu_export.Items.Add(menu_export_HTML);
        menu_export.Items.Add(menu_export_TEXT);
        menu_export.Items.Add(menu_export_MHT);
        menu_export.Items.Add(menu_export_RTF);

        e.Menu.Items.Add(menu_export);

        #endregion
      }
    }

    #endregion

    #region 异步添加ListBoxControl的节点

    /// <summary>
    /// 异步添加ListBoxControl的节点
    /// </summary>
    /// <param name="listBox">System.Windows.Forms.ListBox 对象</param>
    /// <param name="item">内容</param>
    public static void AddListBoxItem(this ListBoxControl listBox, object item, bool containTime = false) {
      if (listBox == null) {
        return;
      }

      var msg = item;
      if (containTime) {
        msg = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} {msg}";
      }

      if (listBox.InvokeRequired) {
        MethodInvoker invoker = new MethodInvoker(delegate {
          listBox.SelectedIndex = listBox.Items.Add(msg);
        });

        listBox.BeginInvoke(invoker, msg);
      } else {
        listBox.SelectedIndex = listBox.Items.Add(msg);
      }
    }

    #endregion

    #region 获取GridView的FormatCondition

    /// <summary>
    /// 根据tag获取
    /// </summary>
    /// <param name="gv"></param>
    /// <param name="tag"></param>
    /// <returns></returns>
    public static StyleFormatCondition GetFormatConditionByTag(this GridView gv, object tag) {
      foreach (StyleFormatCondition condition in gv.FormatConditions) {
        if (condition.Tag == tag) {
          return condition;
        }
      }

      return null;
    }

    #endregion

    #region Mdi Page

    /// <summary>
    /// 关闭当前
    /// </summary>
    /// <param name="mdiManager"></param>
    public static void CloseCurrent(this XtraTabbedMdiManager mdiManager) {
      if (mdiManager.SelectedPage.ShowCloseButton == DefaultBoolean.False) {
        return;
      }

      mdiManager.SelectedPage.MdiChild.Close();
    }

    /// <summary>
    /// 关闭右侧
    /// </summary>
    /// <param name="mdiManager"></param>
    public static void CloseRight(this XtraTabbedMdiManager mdiManager) {
      // 总窗口数
      var count = mdiManager.Pages.Count;

      // 查找当前窗口在的位置
      var index = mdiManager.Pages.IndexOf(mdiManager.SelectedPage);

      // 从后面循环递减
      for (var i = count - 1; i > index; i--) {
        // 窗口
        var page = mdiManager.Pages[i];

        // 不允许关闭
        if (page.ShowCloseButton == DefaultBoolean.False) {
          continue;
        }

        // 当前窗口
        if (page == mdiManager.SelectedPage) {
          continue;
        }

        // close
        mdiManager.Pages[i].MdiChild.Close();
      }

    }

    /// <summary>
    /// 关闭左侧
    /// </summary>
    /// <param name="mdiManager"></param>
    public static void CloseLeft(this XtraTabbedMdiManager mdiManager) {
      // 总窗口数
      var count = mdiManager.Pages.Count;

      // 查找当前窗口在的位置
      var index = mdiManager.Pages.IndexOf(mdiManager.SelectedPage);

      // 从后面循环递减
      for (var i = index - 1; i >= 0; i--) {
        // 窗口
        var page = mdiManager.Pages[i];

        // 不允许关闭
        if (page.ShowCloseButton == DefaultBoolean.False) {
          continue;
        }

        // 当前窗口
        if (page == mdiManager.SelectedPage) {
          continue;
        }

        // close
        mdiManager.Pages[i].MdiChild.Close();
      }

    }

    /// <summary>
    /// 关闭其他
    /// </summary>
    /// <param name="mdiManager"></param>
    public static void CloseOther(this XtraTabbedMdiManager mdiManager) {
      // 总窗口数
      var count = mdiManager.Pages.Count;

      // 从后面循环递减
      for (var i = count - 1; i >= 0; i--) {
        // 窗口
        var page = mdiManager.Pages[i];

        // 不允许关闭
        if (page.ShowCloseButton == DefaultBoolean.False) {
          continue;
        }

        // 当前窗口
        if (page == mdiManager.SelectedPage) {
          continue;
        }

        // close
        mdiManager.Pages[i].MdiChild.Close();
      }

    }

    /// <summary>
    /// 关闭全部
    /// </summary>
    /// <param name="mdiManager"></param>
    public static void CloseAll(this XtraTabbedMdiManager mdiManager) {
      // 总窗口数
      var count = mdiManager.Pages.Count;

      // 从后面循环递减
      for (var i = count - 1; i >= 0; i--) {
        // 窗口
        var page = mdiManager.Pages[i];

        // 不允许关闭
        if (page.ShowCloseButton == DefaultBoolean.False) {
          continue;
        }

        // close
        mdiManager.Pages[i].MdiChild.Close();
      }

    }

    #endregion

    #region 设置时间

    /// <summary>
    /// 设置时间的走动
    /// </summary>
    /// <param name="control"></param>
    public static void SetFullControlTimeMove(this BarItem control, string format = "yyyy-MM-dd HH:mm:ss") {
      // 秒表滴答滴答滴答
      bool tickTick = true;

      // 定时器
      System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
      timer.Interval = 500; // 每隔半秒钟,执行一次
      timer.Tick += (sender, e) => {
        if (tickTick) {
          control.Caption = DateTime.Now.ToString(format);
        } else {
          control.Caption = DateTime.Now.ToString(format);
        }
        tickTick = !tickTick;
      };

      // 定时器开启
      timer.Start();
    }

    #endregion

    #region 焦点定位并选中

    /// <summary>
    /// 焦点定位并选中
    /// </summary>
    /// <param name="control"></param>
    public static void FocusAndSelectAll(this TextEdit control) {
      control.Focus();
      control.SelectAll();
    }

    #endregion

    #region 鼠标行双击判断

    /// <summary>
    /// 
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    public static bool IsMouseDoubleClick(this RowClickEventArgs e) {
      return e.Button == MouseButtons.Left && e.Clicks == 2;
    }

    #endregion

    #region 加载图片

    ///// <summary>
    ///// 加载图片
    ///// </summary>
    ///// <param name="edit"></param>
    ///// <param name="url"></param>
    ///// <returns></returns>
    //public static async Task LoadImageAsync(this PictureEdit edit, string url) {
    //  try {
    //    using (var client = new WebClient()) {
    //      var stream = await client.OpenReadTaskAsync(url);
    //      edit.Image = new Bitmap(stream);
    //    }
    //  } catch {
    //  }
    //}

    #endregion

    /// <summary>
    /// 返回CheckedComboBoxEdit中的选中值集合.  add by geping@2018-09-19
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public static List<T> GetCheckedValues<T>(this CheckedComboBoxEdit checkedComboBoxEdit) {
      var list = Array.ConvertAll(
        checkedComboBoxEdit.Properties.Items.GetCheckedValues().ToArray(),
        new Converter<object, T>(x => x.To<T>()));

      return list.ToList();
    }

    /// <summary>
    /// 返回RepositoryItemCheckedComboBoxEdit中的选中值集合
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public static List<T> GetCheckedValues<T>(this RepositoryItemCheckedComboBoxEdit checkedComboBoxEdit) {
      var list = Array.ConvertAll(
        checkedComboBoxEdit.Items.GetCheckedValues().ToArray(),
        new Converter<object, T>(x => x.To<T>()));

      return list.ToList();
    }
  }
}
